package com.meevle.web;

import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.red5.core.ApplicationSettings;

import com.meevle.business.SetDelegate;
import com.meevle.business.SlotDelegate;
import com.meevle.dao.SetDAO;
import com.meevle.dao.SlotDAO;
import com.meevle.dao.UserDAO;
import com.meevle.utilities.DaoToVoAdapter;
import com.meevle.vo.SetVO;
import com.meevle.vo.SlotVO;
import com.meevle.vo.UserVO;

/**
 * Servlet implementation class FileUploadServlet
 */
public class FileUploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public FileUploadServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	// Called when a file has been submitted
	// Called because file uploads are HTTP POST operations
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		// Setup the various objects used during this upload operation
		// Commons file upload classes are specifically instantiated
		File disk = null;
		FileItem item = null;
		FileItemFactory factory = new DiskFileItemFactory();
		Iterator iter = null;
		List items = null;
		ServletFileUpload upload = new ServletFileUpload(factory);
		ServletOutputStream out = null;

		try {
			// Parse the incoming HTTP request
			// Commons takes over incoming request at this point
			// Get an iterator for all the data that was sent
			// TODO: Leverage generics
			items = upload.parseRequest(req);

			String userName = req.getParameter("userName");
			String setName = req.getParameter("setName");
			int slotIndex = Integer.parseInt(req.getParameter("index"));
			String slotName = req.getParameter("slotName");

			iter = items.iterator();

			// Set a response content type
			res.setContentType("text/xml");

			// Setup the output stream for the return XML data
			out = res.getOutputStream();
			StringBuffer buffer = new StringBuffer();

			buffer.append("<slots>");
			
			// Iterate through the incoming request data
			while (iter.hasNext()) {
				// Get the current item in the iteration
				item = (FileItem) iter.next();

				// If the current item is an HTML form field
				if (item.isFormField()) {
					

					// If the current item is file data
				} else {
					long timestamp = System.currentTimeMillis();
					// Specify where on disk to write the file
					// Using a servlet init param to specify location on disk
					// Write the file data to disk
					// TODO: Place restrictions on upload data
					// disk = new File( getInitParameter( "uploadPath" ) +
					// item.getName() );
					disk = new File(ApplicationSettings.getInstance()
							.getContextFullPath()
							+ ApplicationSettings.getInstance().getUserSetPath(
									userName, setName)
							+ File.separator
							+ String.valueOf(timestamp)
							+ ".mp3");

					item.write(disk);
					
					SetVO setVo = new SetVO();
					UserVO u = new UserVO();
					u.setUsername(userName);
					setVo.setName(setName);
					setVo.setOwner(u);

					SetDAO set = SetDAO.getSet(setVo);
					for (SlotDAO slot : set.getSlots()) {
						if (slot.getSlotIndex() == slotIndex) {
							SetDelegate.removeSlotFromSet(DaoToVoAdapter.getInstance()
									.getSlotFromSlotDAO(slot), setVo);
						}
					}

					String fileDirectory = ApplicationSettings.getInstance().getUserSetPath(userName, setName);
					SlotVO trackVo = new SlotVO();

					trackVo.setName(slotName);
					trackVo.setOwner(DaoToVoAdapter.getInstance().getUserFromUserDAO(
							UserDAO.getUser(new UserVO(userName))));
					trackVo.setTimeCreated(new Timestamp(timestamp));
					trackVo.setFilename(String.valueOf(timestamp)+".mp3");
					trackVo.setDirectory(fileDirectory.replace('\\', '/'));
					trackVo.setIndex(slotIndex);

					// persisting the new slot to the DB
					try {
						if (SlotDelegate.persistSlot(trackVo))
							UserDAO.addSlotToUser(trackVo.getOwner(), trackVo);
						else
							System.out
									.println("\nSlotDelegate: createSlot : Persisten van track naar DB is niet gelukt");
					} catch (Exception e) {
						e.printStackTrace();
					}

					SetDelegate.addSlot(setVo, trackVo);

					// Return an XML node with the file name and size (in bytes)
//					out.println("<file name=\"" + item.getName() + "\" size=\""
//							+ item.getSize() + "\" />");
					buffer.append("<slot>");
					buffer.append("<name>"+trackVo.getName()+"</name>");
					buffer.append("<fileName>"+trackVo.getFilename()+"</fileName>");
					buffer.append("<directory>"+trackVo.getDirectory()+"</directory>");
					buffer.append("<index>"+trackVo.getIndex()+"</index>");
					buffer.append("<timeCreated>"+trackVo.getTimeCreated()+"</timeCreated>");
					buffer.append("</slot>");
				}
			}

			// Close off the response XML data and stream
			
			buffer.append("</slots>");
			out.print(buffer.toString());
			out.close();
			// Rudimentary handling of any exceptions
			// TODO: Something useful if an error occurs
		} catch (FileUploadException fue) {
			fue.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
